package br.uniceub.fsw.agenda.model.dao;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.exception.UniqueConstraintException;
import br.uniceub.fsw.agenda.model.vo.UsuarioVO;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * 06/04/2008
 * @author Rodrigo Uchôa - rodrigo.uchoa@yahoo.com
 *
 */
public class UsuarioDAO extends GenericDAO {
    
    public UsuarioDAO(Connection con) {
        super(con);
    }
    
    /**
     * Busca um usuario pelo login e pela senha (usado no login)
     * @param login
     * @param password
     * @return objeto Usuario correspondente
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public UsuarioVO findByLoginAndPassword(String login, String password) throws
            BusinessException, DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TB_USUARIO");
        query.append(" WHERE DS_LOGIN = ?");
        query.append(" AND DS_SENHA = ?");
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, login);
            st.setString(2, password);
            
            ResultSet rs = st.executeQuery();
            UsuarioVO usuario = null;
           if (rs.next()) {
               usuario = new UsuarioVO();
               usuario.setIdUsuario(rs.getInt("ID_USUARIO"));
               usuario.setNoUsuario(rs.getString("NO_USUARIO"));
               usuario.setDsLogin(rs.getString("DS_LOGIN"));
               usuario.setDsSenha(rs.getString("DS_SENHA"));               
           } else {
                throw new BusinessException("Senha ou usuário inválidos.");
           }
            return usuario;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOUsuario.findByLoginAndPassword()", ex);
        }        
    }

    /**
     * Devolve lista com objetos usuario ordenados por ordem alfabetica
     * @return
     * @throws BusinessException
     * @throws DatabaseException
     */
    public List<UsuarioVO> findAll() throws BusinessException, DatabaseException {
        //string de consulta
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TB_USUARIO ORDER BY NO_USUARIO");
        
        List<UsuarioVO> listaRegistros = new ArrayList<UsuarioVO>();
        
        try {
            //objeto con é herdado da super classe
            Statement st = this.con.createStatement();
            ResultSet rs = st.executeQuery(query.toString());
            while (rs.next()) {
                UsuarioVO usuario = new UsuarioVO();
                
                usuario.setIdUsuario(rs.getInt("ID_USUARIO"));
                usuario.setNoUsuario(rs.getString("NO_USUARIO"));
                usuario.setDsLogin(rs.getString("DS_LOGIN"));
                usuario.setDsSenha(rs.getString("DS_SENHA"));
                
                listaRegistros.add(usuario);
            }
            st.close();
            rs.close();
            return listaRegistros;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro ao buscar usuarios", ex);
        }        
    }
    
    /**
     * Buscar objeto Usuario pelo seu id
     * @param idUsuario código do usuario que se deseja buscar
     * @return objeto Usuario
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public UsuarioVO findById(Integer idUsuario) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TB_USUARIO WHERE ID_USUARIO = ?");
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, idUsuario.toString());
            
            ResultSet rs = st.executeQuery();

            UsuarioVO usuario = new UsuarioVO();
            
            while (rs.next()) {
                usuario.setIdUsuario(rs.getInt("ID_USUARIO"));
                usuario.setNoUsuario(rs.getString("NO_USUARIO"));
                usuario.setDsLogin(rs.getString("DS_LOGIN"));
                usuario.setDsSenha(rs.getString("DS_SENHA"));
            }
            
            st.close();
            rs.close();
            
            return usuario;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOUsuario.findById()", ex);
        }
    }

    /**
     * Buscar lista de usuarios por parte de seu nome
     * @param noUsuario parte do nome dos usuarios que se deseja buscar
     * @return List de objetos Usuario
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public List<UsuarioVO> findAllByNome(String noUsuario) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TB_USUARIO WHERE NO_USUARIO LIKE ? ORDER BY NO_USUARIO");
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            String filtro = "%" + noUsuario + "%";
            st.setString(1, filtro);
            
            List<UsuarioVO> listaRegistros = new ArrayList<UsuarioVO>();
            
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                UsuarioVO usuario = new UsuarioVO();
                usuario.setIdUsuario(rs.getInt("ID_USUARIO"));
                usuario.setNoUsuario(rs.getString("NO_USUARIO"));
                usuario.setDsLogin(rs.getString("DS_LOGIN"));
                usuario.setDsSenha(rs.getString("DS_SENHA"));
                
                listaRegistros.add(usuario);
            }
            st.close();
            rs.close();
            return listaRegistros;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOUsuario.findAllByNome()", ex);
        }
    }

    /**
     * Faz o insert de um novo usuario e devolve a o id recem gerado
     * @param Usuario usuario que se deseja inserir
     * @return ID auto-increment gerado para esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer insert(UsuarioVO usuario) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("INSERT INTO TB_USUARIO(NO_USUARIO, DS_LOGIN, DS_SENHA) ");
        query.append("VALUES (?,?,?)");
        
        //retornar id gerado
        Integer generatedId = null;
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, usuario.getNoUsuario());
            st.setString(2, usuario.getDsLogin());
            st.setString(3, usuario.getDsSenha());
            
            st.executeUpdate();
            
            //pegar id gerado
            ResultSet rs = st.getGeneratedKeys();
            while (rs.next()) {
                generatedId = new Integer(rs.getString(1));                
            }                    
            
            return generatedId;            
        } catch (SQLException ex) {            
            ex.printStackTrace();
            if (ex.getErrorCode() == 1062) {
                throw new UniqueConstraintException(ex.getMessage(), ex);                
            }
            throw new DatabaseException("Erro no DAOUsuario.insert()", ex);            
        }      
    }
    
    /**
     * Faz o update de um usuario
     * @param Usuario usuario que se deseja alterar
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void update(UsuarioVO usuario) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("UPDATE TB_USUARIO SET NO_USUARIO = ?, DS_LOGIN = ?, DS_SENHA = ? ");
        query.append("WHERE ID_USUARIO = ?");             
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, usuario.getNoUsuario());
            st.setString(2, usuario.getDsLogin());
            st.setString(3, usuario.getDsSenha());
            st.setString(4, usuario.getIdUsuario().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOUsuario.update()", ex);
        }      
    }
    
    /**
     * Faz o delete de um usuario
     * @param Usuario usuario que se deseja excluir
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void delete(UsuarioVO usuario) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("DELETE FROM TB_USUARIO ");
        query.append("WHERE ID_USUARIO = ?");
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, usuario.getIdUsuario().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOUsuario.delete()", ex);            
        }      
    }

}
